Auto ScalingのLifeCycleHookがマネジメントコンソールから作成できるようになりました
まいど、大阪の市田です。
Auto Scalingでは「LifeCycleHook」という機能を使って、インスタンスの起動/破棄時にユーザが処理をフックして独自のアクションを実行することが可能です。 この機能を使う時、これまではAPI、CLI、CloudFormationのいずれかを利用する必要がありましたが、今回のアップデートで登録と削除がマネジメントコンソールからできるようになりました。
AWS Developer Forums: Auto Scaling Lifecycle Hooks Enhancements
LifeCycleHookについては、下記を参考にしてもらえればと思います。
【新機能】Auto Scalingのインスタンス起動/破棄時に初期処理/終了処理を追加 – LifeCycleHook機能のご紹介
試してみた
早速試してみたいと思います。
Auto Scaling Groupの作成
まずはAuto Scaling Groupを作りましょう。特別な設定は不要なので普通に作ります。
Auto Scaling Groupが作れたら、新しく追加された「Lifecycle Hooks」タブをクリックします。
「Create Lifecycle Hook」をクリックして下さい。
今回はインスタンスがLaunchされた時のフックを作ります。Terminate時のフックも必要ならもう1つ作成して下さい。
作成出来ました。
無事に作成できたらHookを通知できるようにします。上記の画面では、CloudWatch Eventsの利用が紹介されていたので、リンクにあるドキュメントに従って通知環境を作成します。
Auto Scaling ライフサイクルフック | CloudWatch イベント を使用した通知の受け取り
Lambda Funtionの作成
まずはLambda Functionの作成です。今回はサンプルにあるNode.jsのFunctionをトリガー無しで作成しました。
Function名は分かりやすく「lifecycle-hook」にしています。
このFunctionはイベントだけを記録するものです。
console.log('Loading function'); exports.handler = function(event, context) { console.log("AutoScalingEvent()"); console.log("Event data:\n" + JSON.stringify(event, null, 4)); context.succeed("..."); };
IAM Roleは適当なものを付けてください。
Lambda Functionが作成できたらARNを控えておきましょう。後で使います。
CloudWatch Eventsの設定
次にCloudWatch Eventsを設定していきたいと思います。 先程紹介したドキュメントではAWS CLIによる設定方法が記載されていましたが、マネジメントコンソールでも設定可能です。ここでは両方の方法をご紹介したいと思います。
マネジメントコンソールで設定する場合
最初は、マネジメントコンソールを使った設定方法についてです。CloudWatch Eventsの画面で「Create rule」をクリックします。
Event Sourceの設定で「Service Name」に「Auto Scaling」を選択します。
次に「Event Type」から「Instance Launch and Terminate」を選択してください。
今回はインスタンスLaunch時のLifecycleイベントだけを対象にしたいので、「Specific instance event(s)」を選択してプルダウンから「EC2 Instance-launch Lifecycle Action」を指定します。
次に、対象のオートスケーリンググループを指定してください。今回は対象のグループを指定しましたが、全てのグループを対象にする場合は「Any group name」を指定します。
次にターゲットを設定します。
ターゲットの種類はLambda Functionを選択しましょう。
実行したいLambda Functionを選択します。先程作成したものを選んでください。
最後にルール名を入力して終わりです。今回は「lifecyclehook」としています。
これで、CloudWatch Eventsに「lifecyclehook」というルールができました。
AWS CLIで設定する場合
次は、AWS CLIでCloudWatch Eventsを設定する方法です。マネジメントコンソールで設定された場合はスキップして下さい。
最初にライフサイクルアクションのjsonファイルを作成します。これはAutoScalingでインスタンスがLaunchされるイベントを指定する為です。 今回は「lifecyclehook-launch.json」というファイル名で作成しました。
{ "source": [ "aws.autoscaling" ], "detail-type": [ "EC2 Instance-launch Lifecycle Action" ] }
jsonファイルが作成できたらイベントのソースを定義します。イベントの内容は上記で作成したjsonファイルの通りです。ちなみにルールの名前は「lifecyclefook」にしています。
$ aws events put-rule --name lifecyclefook --event-pattern file://lifecyclehook-launch.json --state ENABLED
コマンドを実行すると、ルールのARNが返ってくるのでこれを控えておきましょう。マネジメントコンソールからも確認できます。
{ "RuleArn": "arn:aws:events:ap-northeast-1:xxxxxxxxxxxx:rule/lifecyclefook" }
次に、Lambda Functionを呼び出すためのアクセス権限をCloudWatch EventsのRulesに付与してください。
$ aws lambda add-permission \ > --function-name lifecycle-hook \ > --statement-id lifecycle-hook-launch-event \ > --action 'lambda:InvokeFunction' \ > --principal events.amazonaws.com \ > --source-arn arn:aws:events:ap-northeast-1:xxxxxxxxxxxx:rule/lifecyclefook
- function-name:先程作成したLambd Functionの名前を指定します。
- source-arn:CloudWatch Eventsで作成したルールのARNです。
次にCloudWatch Eventsのターゲットを作成します。ターゲットは作成したLambda Functionなので、ARNには先程控えておいた関数のものを指定しましょう。
$ aws events put-targets --rule lifecyclefook \ > --targets Id=1,Arn=arn:aws:lambda:ap-northeast-1:xxxxxxxxxxxx:function:lifecycle-hook
これでCloudWatch Eventsに「lifecyclefook」というルールができました。
設定どおり「インスタンスのLaunch」のイベントがトリガーになっています。
実際に確認してみる
それでは、オートスケーリングを実際にスタートさせてみます。
オートスケーリングで起動したインスタンスが「Pending:Wait」になっていることが確認できます。この状態でSSHでサーバにログインして必要な処理を行うことになります。(今回は何もしませんが)
次に、CloudWatch Logsから「LifecycleActionToken」を確認してみましょう。{ $.detail.EC2InstanceId = "<インスタンスID>" }
という形でフィルターするとトークンが記載されたログを抽出できます。
このトークンを用いて「Pending」を次の状態に進めます。
aws autoscaling complete-lifecycle-action \ > --lifecycle-hook-name lifecycle-hook-test \ > --auto-scaling-group-name \ > --lifecycle-action-token xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx \ > --lifecycle-action-result CONTINUE
- lifecycle-hook-name:マネジメントコンソールで作成した時のライフサイクル名です。
- auto-scaling-group-name:対象のオートスケーリンググループ名です。
- lifecycle-action-token:CloudWatch Logsに出力される対象インスタンスのトークン(
LifecycleActionToken
)です。
コマンドを実行すると対象のインスタンスが「InService」になりました。
最後に
ユーザの処理が終わって次の状態に進める「CompleteLifecycleAction」は、上記で見た通りマネジメントコンソールでは出来ないので、CLI等を使う必要があります。 しかし、オートスケーリングの環境では基本的に自動処理を行うケースが多いと思いますので「CompleteLifecycleAction」の処理は自動化するのがいいですね。
以上です。